/*
该文件列举了日志系统的基本用法演示样例，请注意代码间的注释，以便可以得到预期结果
*/

#include "../../include/interface.hpp"


// 通过自主获取logger对象的方式来使用日志系统
void test1()
{
    auto logger = xzt::log::getDefaultLogger();
    for(int i = 0; i < 1000; ++i)
    {
        int idx = i;
        // 用宏函数来调用日志系统的接口
        logger->debug("Debug... - {%d}", idx++);
        logger->info("Info... - {%d}", idx++);
        logger->warn("Warn... - {%d}", idx++);
        logger->error("Error... - {%d}", idx++);
        logger->fatal("Fatal... - {%d}", idx++);
    }
}

// 直接采用默认的logger对象来使用日志系统
void test2()
{
    for(int i = 0; i < 1000; ++i)
    {
        int idx = i;
        // 用宏函数来调用日志系统的接口
        LOG_DEBUG("Debug... - {%d}", idx++);
        LOG_INFO("Info... - {%d}", idx++);
        LOG_WARN("Warn... - {%d}", idx++);
        LOG_ERROR("Error... - {%d}", idx++);
        LOG_FATAL("Fatal... - {%d}", idx++);
    }
}

// 采用默认的logger对象，对其进行配置，然后再来使用日志系统
void test3()
{
    auto logger = xzt::log::getDefaultLogger();
    // 配置日志系统的一些参数
    xzt::log::ResetLimitLevel(logger, xzt::log::Level::value::INFO);
    xzt::log::ResetFormatter(logger, "[%d{%H:%M:%S}] %f:%l [%p] %m%n");  // 注意%d和子格式{}要同时出现才能生效
    std::vector<xzt::log::LogSink::ptr> sinks;
    //sinks.push_back(std::make_shared<xzt::log::StdoutSink>());
    //sinks.push_back(std::make_shared<xzt::log::FileSink>("./log.txt"));
    std::string base_pathname = "./logs/log_";
    size_t max_size = 1024 * 1024 * 2; // 2MB
    sinks.push_back(std::make_shared<xzt::log::RollingBySizeFileSink>(base_pathname, max_size));
    xzt::log::ResetSinks(logger, sinks);

    //for(int i = 0; i < 100000; ++i)
    //{
    //    int idx = i;
    //    // 用宏函数来调用日志系统的接口
    //    logger->debug("Debug... - {%d}", idx++);
    //    logger->info("Info... - {%d}", idx++);
    //    logger->warn("Warn... - {%d}", idx++);
    //    logger->error("Error... - {%d}", idx++);
    //    logger->fatal("Fatal... - {%d}", idx++);
    //}

    size_t count = 1e8;

    for(int i = 0; i < count; ++i)
    {
        int idx = i;
        // 用宏函数来调用日志系统的接口
        logger->debug("Debug... - {%d}", idx++);
        logger->info("Info... - {%d}", idx++);
        logger->warn("Warn... - {%d}", idx++);
        logger->error("Error... - {%d}", idx++);
        logger->fatal("Fatal... - {%d}", idx++);

        sleep(1);
    }
}

// 创建并添加管理自定义的日志器对象
void test4()
{
    // 自定义日志器对象，并使用自定义的日志器对象来使用日志系统
    // 利用建造者来构建日志器对象，注意日志器名称必须显示给定，其他可以省略使用默认
    // bulider对象利用多态特性，可以构建同步或异步的日志器对象
    xzt::log::LoggerBulider::ptr builder = std::make_shared<xzt::log::LocalLoggerBulider>();
    builder->bulidLoggerName("my_logger");
    builder->bulidLoggerType(xzt::log::LoggerType::LOGGER_ASYNC);  // 设定为异步日志器，默认是同步日志器
    // builder->bulidLimitLevel(xzt::log::Level::value::INFO);  // 设置截断日志等级
    // builder->bulidFormatter("[%d{%H:%M:%S}] %f:%l [%p] %m%n");  // 设置日志格式
    // 利用buildSink()函数来增加日志落地，实现多种日志落地方式
    // builder->bulidSink<xzt::log::StdoutSink>();  // 增加日志落地
    // builder->bulidSink<xzt::log::FileSink>("./log.txt");
    // builder->bulidSink<xzt::log::RollingBySizeFileSink>(base_pathname, max_size);
    // 开启异步日志器的非安全模式，默认是安全模式, 非安全模式下数据池会无限扩容，可能会导致内存泄漏
    // builder->bulidEnableAsyncUnSafe();
    auto my_logger = builder->bulid();
    // 利用日志器管理器来统一管理日志器对象
    xzt::log::LoggerManager::getInstance().addLogger(my_logger);  // 全局日志器会自动注册到日志器管理器中
    
    if(xzt::log::LoggerManager::getInstance().hasLogger("my_logger") == false)
    {
        std::cout << "my_logger not found" << std::endl;
    }
    else
    {
        std::cout << "my_logger found" << std::endl;
    }
}

int main()
{
    // test1();
    // test2();
    test3();
    // test4();
    return 0;
}
